Skip to content

Feature/allowed method interceptor #35273

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

SRIRAM9487
Copy link

Support HTTP method-restricted interceptors in InterceptorRegistration

This PR implements #35272, adding support for restricting HandlerInterceptor registration to specific HTTP methods.

Motivation

Spring MVC currently allows interceptors to be applied based on path patterns, but not HTTP methods. When method-based filtering is needed, it must be manually implemented within the interceptor itself:

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
    if (!"POST".equals(request.getMethod())) {
        return true;
    }
    // Logic here
    return true;
}

This approach clutters interceptor logic with method checks and duplicates similar logic across interceptors when needed. Centralizing HTTP method filtering in the registration API provides a cleaner and more declarative configuration style.

Solution

This PR introduces a new method to InterceptorRegistration:

public InterceptorRegistration allowedMethods(HttpMethod... methods)

This allows restricting the interceptor to specific HTTP methods like GET, POST, etc. Under the hood, the framework wraps the given HandlerInterceptor in a new MethodInterceptor that delegates calls only when the request's HTTP method matches one of the allowed methods.

registry.addInterceptor(new MyInterceptor())
        .addPathPatterns("/api/**")
        .allowedMethods(HttpMethod.POST, HttpMethod.PUT);

The interceptor will now be invoked only for POST and PUT requests matching /api/**.

Implementation Details

  • InterceptorRegistration stores allowed HTTP methods as a Set<String>.
  • If any methods are configured, it wraps the given interceptor using the new MethodInterceptor.
  • MethodInterceptor checks the request's method before delegating to the original interceptor.
  • The implementation is fully backward compatible; if no methods are provided, all HTTP methods are allowed (default behavior).

Tests

A dedicated test class MethodInterceptorTests is included to validate:

  • Delegation occurs only for allowed HTTP methods.
  • Interceptor is skipped for disallowed methods.
  • All interceptor lifecycle methods (preHandle, postHandle, afterCompletion) are covered.

Example

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new AuditInterceptor())
                .addPathPatterns("/admin/**")
                .allowedMethods(HttpMethod.GET);
    }
}

In this example, AuditInterceptor will apply only for GET requests under /admin/**.

Compatibility

  • No breaking changes introduced.
  • The feature is opt-in.
  • Reuses existing Spring MVC components (MappedInterceptor, HandlerInterceptor) without exposing new public types.

Signed-off-by: SRIRAM9487 <sriram9487tk@gmail.com>
Added comprehensive unit tests covering all branches of MethodInterceptor:
- preHandle: allowed and disallowed methods
- postHandle: allowed and disallowed methods
- afterCompletion: allowed and disallowed methods

Signed-off-by: SRIRAM9487 <sriram9487tk@gmail.com>
@SRIRAM9487 SRIRAM9487 force-pushed the feature/allowed-method-interceptor branch from 845a609 to 7161bdc Compare August 2, 2025 09:24
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Aug 2, 2025
@SRIRAM9487
Copy link
Author

SRIRAM9487 commented Aug 2, 2025

@bclozel Thanks for the feedback on #35272. Understood that this feature is not currently planned.

I'll consider maintaining it as an external utility or extension module, since I still believe this helps reduce boilerplate and improves clarity in interceptor setups.

Appreciate your time and the review!

@bclozel
Copy link
Member

bclozel commented Aug 2, 2025

We have not declined nor reviewed this yet. We don't need both an issue and a PR so we closed the other one.

@SRIRAM9487
Copy link
Author

Thanks for the clarification, @bclozel.
Looking forward to your review once it's in the queue. Let me know if anything needs to be adjusted in the meantime!

@rissay2015
Copy link

Until then (the review by those grannies) :
->You can work on exclude methodes : applying that interceptor to all except this methodes ....
-> feels like we must fall back to manual logic inside the interceptor for anything more complex.
Otherwise that was impressive young man.

Copy link
Contributor

@rstoyanchev rstoyanchev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aside from the comments below, generally the request seems reasonable with the following implementation related points:

  • The existing MappedInterceptor could be enhanced instead to support mapping by HTTP method.
  • The terminology allowedMethods could be just httpMethods, or include/excludeHttpMethods for consistency with include/excludePatterns.

<factorypathentry kind="EXTJAR" id="/home/sriram/.gradle/caches/modules-2/files-2.1/org.pcollections/pcollections/4.0.1/59f3bf5fb28c5f5386804dcf129267416b75d7c/pcollections-4.0.1.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="EXTJAR" id="/home/sriram/.gradle/caches/modules-2/files-2.1/com.uber.nullaway/nullaway/0.12.7/1a813b7d156768204b0c8d52ba0632a8db6fbe12/nullaway-0.12.7.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="EXTJAR" id="/home/sriram/.gradle/caches/modules-2/files-2.1/com.google.guava/failureaccess/1.0.3/aeaffd00d57023a2c947393ed251f0354f0985fc/failureaccess-1.0.3.jar" enabled="true" runInBatchMode="false"/>
</factorypath>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These seem to have been committed by mistake. Could you please remove them from the pull request.

/**
* Add patterns for URLs the interceptor should be included in.
* <p>For pattern syntax see {@link PathPattern} when parsed patterns
* <p>
* For pattern syntax see {@link PathPattern} when parsed patterns
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a number of Javadoc style changes, probably applied by the IDE. Could you please undo those? They are not related and in any case inconsistent with the rest of the codebase.

* @since 5.0.3
*/
public InterceptorRegistration addPathPatterns(List<String> patterns) {
this.includePatterns = (this.includePatterns != null ?
this.includePatterns : new ArrayList<>(patterns.size()));
this.includePatterns = (this.includePatterns != null ? this.includePatterns : new ArrayList<>(patterns.size()));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likewise there are a number of code style changes. Please, undo those.

@rstoyanchev rstoyanchev added in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement labels Aug 7, 2025
@rstoyanchev rstoyanchev added this to the 7.0.x milestone Aug 7, 2025
@rstoyanchev rstoyanchev removed the status: waiting-for-triage An issue we've not yet triaged or decided on label Aug 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants